package com.pay.service.impl;

import com.pay.constant.Constant;
import com.pay.entity.BankDetail;
import com.pay.entity.BankType;
import com.pay.entity.CashDetails;
import com.pay.entity.CashRule;
import com.pay.entity.Merchant;
import com.pay.entity.MerchantAccount;
import com.pay.enums.MerchantAccountTypeEnums;
import com.pay.exception.ServiceException;
import com.pay.mapper.CashDetailsMapper;
import com.pay.service.IBankDetailService;
import com.pay.service.IBankTypeService;
import com.pay.service.ICashDetailsService;
import com.pay.service.ICashRuleService;
import com.pay.service.IMerchantAccountService;
import com.pay.service.IMerchantService;
import com.pay.utils.BasePage;
import com.pay.utils.FunctionUtils;
import com.pay.utils.ResponseData;

import cn.hutool.core.util.StrUtil;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Peng
 * @since 2018-12-15
 */
@Service
public class CashDetailsServiceImpl extends ServiceImpl<CashDetailsMapper, CashDetails> implements ICashDetailsService {

	@Autowired
	private ICashRuleService cashRuleService ;
	
	@Autowired
	private IMerchantService merchantService ;
	
	@Autowired
	private IBankDetailService bankDetailService ;
	
	@Autowired
	private IBankTypeService bankTypeService ;
	
	@Autowired
	private IMerchantAccountService merchantAccountServicer ;
	
	private Lock lock = new ReentrantLock() ;
	
	@Override
	public void getList(CashDetails cashDetails, BasePage<CashDetails> page) {
		QueryWrapper<CashDetails> ew = new QueryWrapper<CashDetails>();
		if(cashDetails.getMerid() != null) {
			ew.eq("merid", cashDetails.getMerid()) ;
		}
		
		if(page.isPage()) {
			super.page(page, ew) ;
		}else {
			List<CashDetails> data = super.list(ew);
			int total = super.count(ew);
			page.setRecords(data) ;
			page.setTotal(total) ;
		}
		for(CashDetails details : page.getRecords()) {
			Merchant merchant = merchantService.getById(details.getMerid());
			BankDetail bankDetail = bankDetailService.getById(details.getBankid());
			BankType bankType = bankTypeService.getById(bankDetail.getTypeid());
			bankDetail.setBankType(bankType);
			
			details.setMerchant(merchant);
			details.setBankDetail(bankDetail);
		}
	}

	@Override
	public ResponseData doCash(CashDetails cashDetail) {
		try {
			lock.lock();
			CashRule rule = cashRuleService.getOne(null);
			if(cashDetail.getBankid() == null) {
				return ResponseData.baseError("请选择一张银行卡") ;
			}
			if(cashDetail.getCashmoney() == null) {
				return ResponseData.baseError("提现金额不能为空") ;
			}
			if(cashDetail.getCashmoney().compareTo(rule.getMinval()) < 0 || cashDetail.getCashmoney().compareTo(rule.getMaxval()) > 0) {
				return ResponseData.baseError("提现金额必须在" + rule.getMinval() + "到" + rule.getMaxval() + "之间") ;
			}
			MerchantAccount merchantAccount = merchantAccountServicer.getByMerId(cashDetail.getMerid());
			if(merchantAccount.getMoney().compareTo(cashDetail.getCashmoney()) < 0) {
				return ResponseData.baseError("提现金额超过余额") ;
			}
			String result = merchantAccountServicer.insertAccountDetail(cashDetail.getMerid(), MerchantAccountTypeEnums.cash.getId(), Constant.pay_out, cashDetail.getCashmoney(), "提现");
			if(StrUtil.isNotBlank(result)) {
				throw new ServiceException("提现失败") ;
			}
			
			BigDecimal scale = FunctionUtils.mul(cashDetail.getCashmoney(),rule.getScale() , 2) ;
			BigDecimal realmoney = FunctionUtils.sub(cashDetail.getCashmoney(), scale, 2) ;
			cashDetail.setRealmoney(realmoney);
			return super.save(cashDetail) ? ResponseData.ok() : ResponseData.baseError("提现失败") ;
		}catch(Exception e) {
			e.printStackTrace(); 
			throw e; 
		}finally {
			lock.unlock();
		}
	}

	@Override
	public ResponseData doCashPreper(Integer id, Integer status) {
		try {
			lock.lock();
			CashDetails cashDetail = super.getById(id);
			if(cashDetail.getStatus() != Constant.cash_ing) {
				return ResponseData.baseError("状态异常") ;
			}
			
			cashDetail.setEndtime(new Date());
			cashDetail.setStatus(status);
			boolean result = super.updateById(cashDetail);
			if(!result) {
				throw new ServiceException("处理失败") ;
			}
			if(status == Constant.cash_reject) {
				//提现驳回
				String moneyResult = merchantAccountServicer.insertAccountDetail(cashDetail.getMerid(), 
						MerchantAccountTypeEnums.cash_reject.getId(), Constant.pay_in, cashDetail.getCashmoney(), "提现驳回") ;
				if(StrUtil.isNotBlank(moneyResult)) {
					throw new ServiceException("处理失败") ;
				}
			}
		}catch (Exception e) {
			e.printStackTrace();
			throw e;  
		}finally {
			lock.unlock();
		}
		
		return ResponseData.ok() ;
	}

}
